<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Example: Reset Schedule Graph</title>
  <script type="text/javascript" src="../../highlight.pack.js"></script>
  <script type="text/javascript" src="../../highlightCode.js"></script>
  <link href='../../highlight.css' rel='stylesheet' />
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="svg.js"></script>
<script src="svg.intersections.js"></script>


<style type="text/css">
<!--
 .noselect {
  -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
     -khtml-user-select: none; /* Konqueror HTML */
       -moz-user-select: none; /* Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome and Opera */
       unselectable="on"
 onselectstart="return false;"
 onmousedown="return false;"
}

.grid line {
  stroke: lightgrey;
  stroke-opacity: 0.7;
  shape-rendering: crispEdges;
}

.grid path {
  stroke-width: 0;
}
-->
</style>

</head>
<body style='padding:10px;font-family:arial'>
<center>
<h4>Example: Reset Schedule Graph</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
The setpoint of a controller is automatically changed via a sensor's input value. The reset schedule follows an adjustable path located in a graph.
</div>
<table><tr>
<td>
<div style="padding:10px;width:400px;text-align:justify">

<b>Scenerio:</b><br />
 The the desired set point is where the transmitter input value intersects the path.
 The set point span and upper & lower limits are adjustable. The path's curvature is also ajustable.<p></p>
  <b>Change Reset Schedule Path - Drag:</b><br>
 Orange Circle - Sets the upper limits<br>
Green Circle - Sets the lower limits<br>
Blue Circle - Sets the curvature of setpoint path.<br><br>

<div >Simulate Transmitter Input:<br>
<input  onmousedown=simulateTransmitterInput() onmousemove=simulateTransmitterInput() type="range" id=transmitterRangeValue style=width:330px min=0 max=100 step=1 value=40 />
<input type="text" style=width:35px id=rangeValue value=40 />
</div><p></p>
<center> SetPoint = <input onfocus=blur() style='text-align:center;font-weight:bold;width:40px;border:2px solid red;' id=setPointValue type="text" value=66.7 />
</center>
</div>
</td>
<td>
<div id="svgDiv" style='width:600px;height:600px;'>
<svg id=mySVG  width=600 height=600 onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) >
<defs>
<marker id="arrowEnd" viewBox="0 0 8000 8000" refX="280" refY="150" markerUnits="strokeWidth" markerWidth="300" markerHeight="300" orient="auto" fill="black" stroke-linejoin="bevel">
<path id="arrowEndPath" stroke="RGB(0,0,0)" stroke-width="5" d="M2 59,293 148,1 243,121 151,Z"/>
</marker>
<marker id="arrowEndRed" viewBox="0 0 8000 8000" refX="280" refY="150" markerUnits="strokeWidth" markerWidth="300" markerHeight="300" orient="auto" fill="red" stroke-linejoin="bevel">
<path id="arrowEndPath" stroke="RGB(0,0,0)" stroke-width="5" d="M2 59,293 148,1 243,121 151,Z"/>
</marker>
</defs>
<g id=insersectG  transform="translate(60,40)"/>
<foreignObject width=100% height=40 x=180 y=-30 transform="rotate(90)" >
<div style=font-weight:bold >Set Point</div>
</foreignObject>
<foreignObject width=100% x=260 y=565 >
<div style=font-weight:bold >Transmitter Input Value</div>
</foreignObject>


<g id="setpointResetChart" class="noselect" transform="translate(60,40)"></g>
<g id=resetPathG transform="translate(60,40)">
<line id=upperLimitLine x1="0" y1="0" x2="100" y2="0" stroke='blue' stroke-width=3 />
<line id=lowerLimitLine x1="400" y1="500" x2="500" y2="500" stroke='blue' stroke-width=3 />
<path id=resetPath fill="none" d="M100,0 Q250,250 400,500"  stroke='blue' stroke-width=3 />


<circle class=dragTarget id="upperDot" transform="translate(100,0)"  r=10 fill="darkorange" />
<circle class=dragTarget id="lowerDot"  transform="translate(400,500)"  r=10 fill="green" />
<circle class=dragTarget   id="curveDot"  transform="translate(250,250)"  r=10 fill="blue" stroke="red" stroke-width=1 />
<line id=transInputLine pointer-events="none" x1="200" y1="500" x2="200" y2="0" stroke='black' stroke-width=2 stroke-dasharray="8,8" marker-end="url(#arrowEnd)" />
<line id=setPointLine pointer-events="none"  x1="250" y1="250" x2="0" y2="250" stroke='red' stroke-width=2 stroke-dasharray="8,8" marker-end="url(#arrowEndRed)" />
<circle  id="redDot"  pointer-events="none"   r=5 fill="red" />
</g>
<polyline display="none" id=curveSetLine fill="none" stroke="grey" stroke-width="1" />

</svg>
</div>
</td>
</tr></table>
  <br />SVG Source:
  <div id=svgSourceDiv style=overflow:auto;width:100%;height:1px;text-align:left; /></div>
  Javascript:
  <div id=jsCodeDiv style=overflow:auto;width:100%;text-align:left; /></div><p></p>
</center>
<script id=myScript>
function buildResetGraph()
{

var width=500
var height=500



//  X scale will use the index of our data
var xScale = d3.scaleLinear()
    .domain([0,100]) // input
    .range([0, width]); // output

// Y scale will use the randomly generate number
var yScale = d3.scaleLinear()
    .domain([0,100]) // input
    .range([height, 0]); // output

  // gridlines in x axis function
function make_x_gridlines() {
    return d3.axisBottom(xScale)
       // .ticks(5)
}

// gridlines in y axis function
function make_y_gridlines() {
    return d3.axisLeft(yScale)
       // .ticks(5)
}

var graphG=d3.select("#setpointResetChart")
// add the X gridlines
  graphG.append("g")
      .attr("class", "grid")
      .attr("transform", "translate(0," + height + ")")
      .call(make_x_gridlines()
          .tickSize(-height)
          .tickFormat("")
      )

  // add the Y gridlines
  graphG.append("g")
      .attr("class", "grid")
      .call(make_y_gridlines()
          .tickSize(-width)
          .tickFormat("")
      )



// Call the x axis in a group tag
graphG.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom

// Call the y axis in a group tag
graphG.append("g")
    .attr("class", "y axis")
    .call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft


}

var IntersectionPoints
function createTransmitterIntersect()
{

var draw = SVG('insersectG').size(500, 500),
    line  = SVG.adopt(transInputLine),        //
    path  = SVG.adopt(resetPath),
    IntersectionPoints;


    //line.attr("id","intersectLine")
   // path.attr("id","intersectPath")
    //path.attr("fill","none")
    IntersectionPoints = line.intersectsPath(path);


    var cx=IntersectionPoints[0].x
    var cy=IntersectionPoints[0].y
     console.log([cx,cy])
     redDot.setAttribute("cx",cx)
     redDot.setAttribute("cy",cy)
    transInputLine.setAttribute("x2",cx)
    transInputLine.setAttribute("y2",cy)


    setPointLine.setAttribute("x1",cx)
    setPointLine.setAttribute("y1",cy)
    setPointLine.setAttribute("x2",0)
    setPointLine.setAttribute("y2",cy)

    var sp=100-(cy/500)*100


    setPointValue.value=sp.toFixed(1)
}
//-----slider-------------

function simulateTransmitterInput()
{
    var transmitterInput=+transmitterRangeValue.value
      rangeValue.value=transmitterInput

      var transmitterInputX=(transmitterInput/100)*500
  var upperMaxX=+upperLimitLine.getAttribute("x2")
  var lowerMinX=+lowerLimitLine.getAttribute("x1")

  var upperMinY=+upperLimitLine.getAttribute("y1")
  var lowerMaxY=+lowerLimitLine.getAttribute("y1")

      if(transmitterInputX>=upperMaxX&&transmitterInputX<=lowerMinX)
      {

          transInputLine.setAttribute("x1",transmitterInputX)
          transInputLine.setAttribute("x2",transmitterInputX)
          transInputLine.setAttribute("y2",upperMinY)

            var path=SVG.adopt(resetPath)

           var line=SVG.adopt(transInputLine)

           IntersectionPoints = line.intersectsPath(path);


    var cx=IntersectionPoints[0].x
    var cy=IntersectionPoints[0].y
     console.log([cx,cy])
     redDot.setAttribute("cx",cx)
     redDot.setAttribute("cy",cy)
    transInputLine.setAttribute("x2",cx)
    transInputLine.setAttribute("y2",cy)


    setPointLine.setAttribute("x1",cx)
    setPointLine.setAttribute("y1",cy)
    setPointLine.setAttribute("x2",0)
    setPointLine.setAttribute("y2",cy)

    var sp=100-(cy/500)*100
    console.log(sp.toFixed(1))

    setPointValue.value=sp.toFixed(1)
    }
}

//===========================DRAG DOTS===================================
var TransformRequestObj
var TransList
var DragTarget=null;
var Dragging = false;
var OffsetX = 0;
var OffsetY = 0;
//---mouse down over element---
function startDrag(evt)
{
	if(!Dragging) //---prevents dragging conflicts on other draggable elements---
	{
		if(evt.target.getAttribute("class")=="dragTarget")
		{
			DragTarget = evt.target;
			DragTarget.setAttribute("style","cursor:move")
			//---reference point to its respective viewport--
			var pnt = DragTarget.ownerSVGElement.createSVGPoint();
			pnt.x = evt.clientX;
			pnt.y = evt.clientY;
			//---elements transformed and/or in different(svg) viewports---
			var sCTM = DragTarget.getScreenCTM();
			var Pnt = pnt.matrixTransform(sCTM.inverse());

			TransformRequestObj = DragTarget.ownerSVGElement.createSVGTransform()
			//---attach new or existing transform to element, init its transform list---
			var myTransListAnim=DragTarget.transform
			TransList=myTransListAnim.baseVal

			OffsetX = Pnt.x
			OffsetY = Pnt.y
            if(DragTarget.getAttribute("id")=="curveDot")
            showCurveSetLine()

			Dragging=true;
		}
	}
}
//---mouse move---
function drag(evt)
{
	if(Dragging)
	{
		var pnt = DragTarget.ownerSVGElement.createSVGPoint();
		pnt.x = evt.clientX;
		pnt.y = evt.clientY;
		//---elements in different(svg) viewports, and/or transformed ---
		var sCTM = DragTarget.getScreenCTM();
		var Pnt = pnt.matrixTransform(sCTM.inverse());
		Pnt.x -= OffsetX;
		Pnt.y -= OffsetY;

		TransformRequestObj.setTranslate(Pnt.x,Pnt.y)
		TransList.appendItem(TransformRequestObj)
		TransList.consolidate()
var upperMaxX=+upperLimitLine.getAttribute("x2")
  var lowerMinX=+lowerLimitLine.getAttribute("x1")

  var upperMinY=+upperLimitLine.getAttribute("y1")
  var lowerMaxY=+lowerLimitLine.getAttribute("y1")


          var upperDotMatrix=upperDot.getCTM()

        if(DragTarget.getAttribute("id")=="upperDot"&&upperDotMatrix.e-60>=0&&upperDotMatrix.f-40>=0)
        {
            var currentMatrix = DragTarget.getCTM()
           upperLimitLine.setAttribute("y1",currentMatrix.f-40)
           upperLimitLine.setAttribute("y2",currentMatrix.f-40)
           upperLimitLine.setAttribute("x2",currentMatrix.e-60)
         resetPath.setAttribute("y1",currentMatrix.f-40)
        resetPath.setAttribute("x1",currentMatrix.e-60)

        }

          var lowerDotMatrix=lowerDot.getCTM()
        if(DragTarget.getAttribute("id")=="lowerDot"&&lowerDotMatrix.e-60<=500&&lowerDotMatrix.f-40<=500)
        {
            var currentMatrix = DragTarget.getCTM()
           lowerLimitLine.setAttribute("y1",currentMatrix.f-40)
           lowerLimitLine.setAttribute("y2",currentMatrix.f-40)
           lowerLimitLine.setAttribute("x1",currentMatrix.e-60)
           resetPath.setAttribute("y2",currentMatrix.f-40)
          resetPath.setAttribute("x2",currentMatrix.e-60)

        }


            var matrixCurveDot = curveDot.getCTM()

            var curveX=matrixCurveDot.e
            var curveY=matrixCurveDot.f

            var matrixupperDot = upperDot.getCTM()
            var topX=matrixupperDot.e-60
            var topY=matrixupperDot.f-40
            var matrixlowerDot = lowerDot.getCTM()
            var botX=matrixlowerDot.e -60
            var botY=matrixlowerDot.f-40
            var d="M"+topX+","+topY+" Q"+curveX+","+curveY+" "+botX+","+botY
            resetPath.setAttribute("d",d)


            var path=SVG.adopt(resetPath)




        transInputLine.setAttribute("y2",0)
           var line=SVG.adopt(transInputLine)

           IntersectionPoints = line.intersectsPath(path);


    var cx=IntersectionPoints[0].x
    var cy=IntersectionPoints[0].y
     console.log([cx,cy])
     redDot.setAttribute("cx",cx)
     redDot.setAttribute("cy",cy)
    transInputLine.setAttribute("x2",cx)
    transInputLine.setAttribute("y2",cy)


    setPointLine.setAttribute("x1",cx)
    setPointLine.setAttribute("y1",cy)
    setPointLine.setAttribute("x2",0)
    setPointLine.setAttribute("y2",cy)

    var sp=100-(cy/500)*100
    console.log(sp.toFixed(1))

    setPointValue.value=sp.toFixed(1)

                 if(DragTarget.getAttribute("id")=="curveDot")
            showCurveSetLine()


	}
}
//--mouse up---
function endDrag()
{
	Dragging = false ;
    curveSetLine.setAttribute("display","none")
    DragTarget.setAttribute("style","cursor:default")
showSourceSVG()

}

function showCurveSetLine()
{
   curveSetLine.setAttribute("display","block")
    var matrixCurveDot = curveDot.getCTM()

    var curveX=matrixCurveDot.e
    var curveY=matrixCurveDot.f

    var matrixupperDot = upperDot.getCTM()
    var topX=matrixupperDot.e
    var topY=matrixupperDot.f
    var matrixlowerDot = lowerDot.getCTM()
    var botX=matrixlowerDot.e
    var botY=matrixlowerDot.f
    var points=topX+","+topY+" "+curveX+","+curveY+" "+botX+","+botY
    curveSetLine.setAttribute("points",points)


}
</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{   buildResetGraph()
   createTransmitterIntersect()
   	showSourceSVG()
	showSourceJS()

}


</script>
<script>

  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
  ga('create', 'UA-88028738-1', 'auto');
  ga('send', 'pageview');


</script>

</body>

</html>